(function (factory) {
    let global = typeof globalThis !== 'undefined' ? globalThis :
        typeof self !== "undefined" ? self :
            typeof window !== "undefined" ? window :
                typeof global !== "undefined" ? global : {};
    if (typeof exports === 'object' && typeof module === 'object'){ //CommonJS
        module.exports = factory(global);
    }else { //全局变量
        global.ImgCode = factory(global);
    }
})(function (global) {
    let document = global?.document;
    if (!document) return console.error('缺少 document 对象！');

    /**构建视频取帧对象，可以获得视频指定时间的图片
     * @param {String|File} file 视频文件，可以是src地址，也可以是File对象
     * @param {Object} [op] 配置参数，
     * @param {Number} [op.width] 导出图片的宽度，默认：视频原宽度
     * @param {String} [op.type] 导出图片的文件的格式(参考 HTMLCanvasElement.toBlob 方法)，默认：image/jpeg
     * @param {Number} [op.quality] 导出图片的质量(参考 HTMLCanvasElement.toBlob 方法)，默认：0.8
     * @returns {VideoFrame} 内置方法 capture
     * @constructor
     */
    function VideoFrame(file, op){
        if (!(this instanceof VideoFrame)) return new VideoFrame(file, op);
        op = op || {};
        op.type = op.type || 'image/jpeg';
        op.quality = op.quality || 0.8;
        let video = document.createElement('video');
        video.setAttribute('crossOrigin', 'anonymous');
        let canvas = document.createElement('canvas');
        let ctx = canvas.getContext('2d');

        this.list = []; //队列列表，格式：[{time, resolve},...]
        this.row = false; //当前队列元素，格式：{time, resolve}
        this.status = 0; // 状态：0加载中，1加载完成，2捕获中

        let _this = this;

        video.addEventListener('loadeddata', ()=>{
            _this.status = 1;
            let scale = op.width > 0 ? op.width/video.videoWidth : 1;
            canvas.width = Math.ceil(video.videoWidth * scale);
            canvas.height = Math.ceil(video.videoHeight * scale);
            _this.__run();
        })
        video.addEventListener('seeked', ()=>{
            if (!_this.row) return;
            setTimeout(()=>{
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
                canvas.toBlob((blob)=>{
                    _this.row.resolve({
                        url: URL.createObjectURL(blob),
                        blob: blob,
                    })
                    _this.row = false;
                    _this.status = 1;
                    _this.__run();
                }, op.type, op.quality)
            },10)
        })

        video.src = typeof file === 'string' ? file : URL.createObjectURL(file);
        this.video = video;
        this.canvas = canvas;
    }

    VideoFrame.prototype.__run = function(){
        if (this.status !== 1 || this.list.length <= 0) return;
        this.status = 2;
        this.row = this.list.shift();
        this.video.currentTime = this.row.time;
    }
    VideoFrame.prototype.capture = function(time){
        let _this = this;
        return new Promise(function (resolve){
            _this.list.push({
                time: time,
                resolve: resolve,
            })
            _this.__run();
        })
    }

    return VideoFrame;
})